#pragma once


#include <stdarg.h>
#include "utils/TimeUtil.h"
#include "utils/FileUtil.h"
#include "utils/Thread.h"
#include "LogLevel.h"
#include "LogEventImp.h"
#include "LoggerManager.h"

#define LLV_TRACE           log::LogLevel::ELevel::TRACE
#define LLV_DEBUG           log::LogLevel::ELevel::DEBUG
#define LLV_INFO            log::LogLevel::ELevel::INFO
#define LLV_WARN            log::LogLevel::ELevel::WARN
#define LLV_ERROR           log::LogLevel::ELevel::ERROR

#define GET_LOGGER_BY_NAME(name) \
    log::LoggerManager::instance()->getLogger(name)

static log::Logger::ptr g_sysLogger = GET_LOGGER_BY_NAME("system");

#define LOCAL_INFO \
    utils::Thread::getId() \
    , utils::TimeUtil::getCurrentDateTime("%4Y%2m%2d%2H%2M%2S") \
    , utils::FileUtil::getFileNameFromDir(__FILE__) \
    , __FUNCTION__, __LINE__ 

#define LOG_LEVEL(logger, level) \
    if (level >= logger->getLevel()) \
        log::LogEventImp(logger, level, LOCAL_INFO).stream()

#define LOG_FMT_LEVEL(logger, level, fmt, ...) \
    if (level >= logger->getLevel()) \
        log::LogEventImp(logger, level, LOCAL_INFO).format(fmt, __VA_ARGS__)

#define LOG_TRACE(logger)                        LOG_LEVEL(logger, LLV_TRACE)
#define LOG_DEBUG(logger)                        LOG_LEVEL(logger, LLV_DEBUG)
#define LOG_INFO(logger)                         LOG_LEVEL(logger, LLV_INFO)
#define LOG_WARN(logger)                         LOG_LEVEL(logger, LLV_WARN)
#define LOG_ERROR(logger)                        LOG_LEVEL(logger, LLV_ERROR)

#define LOG_FMT_TRACE(logger, fmt, ...)          LOG_FMT_LEVEL(logger, LLV_TRACE, fmt, __VA_ARGS__)
#define LOG_FMT_DEBUG(logger, fmt, ...)          LOG_FMT_LEVEL(logger, LLV_DEBUG, fmt, __VA_ARGS__)
#define LOG_FMT_INFO(logger, fmt, ...)           LOG_FMT_LEVEL(logger, LLV_INFO,  fmt, __VA_ARGS__)
#define LOG_FMT_WARN(logger, fmt, ...)           LOG_FMT_LEVEL(logger, LLV_WARN,  fmt, __VA_ARGS__)
#define LOG_FMT_ERROR(logger, fmt, ...)          LOG_FMT_LEVEL(logger, LLV_ERROR, fmt, __VA_ARGS__)

#define SYS_TRACE()                              LOG_TRACE(g_sysLogger)
#define SYS_DEBUG()                              LOG_DEBUG(g_sysLogger)
#define SYS_INFO()                               LOG_INFO(g_sysLogger)
#define SYS_WARN()                               LOG_WARN(g_sysLogger)
#define SYS_ERROR()                              LOG_ERROR(g_sysLogger)

#define SYS_FMT_TRACE(fmt, ...)                  LOG_FMT_TRACE(g_sysLogger, fmt, __VA_ARGS__)
#define SYS_FMT_DEBUG(fmt, ...)                  LOG_FMT_DEBUG(g_sysLogger, fmt, __VA_ARGS__)
#define SYS_FMT_INFO(fmt, ...)                   LOG_FMT_INFO(g_sysLogger,  fmt, __VA_ARGS__)
#define SYS_FMT_WARN(fmt, ...)                   LOG_FMT_WARN(g_sysLogger,  fmt, __VA_ARGS__)
#define SYS_FMT_ERROR(fmt, ...)                  LOG_FMT_ERROR(g_sysLogger, fmt, __VA_ARGS__)
